using Microsoft.Extensions.Configuration;
using SqlInjectionScanner.Models;
using System.Data;
using System.Text.RegularExpressions;

namespace SqlInjectionScanner.Core
{
    /// <summary>
    /// 注入检测器
    /// </summary>
    public class InjectionDetector
    {
        private readonly List<InjectionPattern> _patterns;

        // 修改InjectionDetector构造函数
        public InjectionDetector(IConfiguration configuration)
        {
            _patterns = configuration.GetSection("InjectionPatterns")
                .Get<List<InjectionPattern>>() ?? InitializePatterns();
        }

        /// <summary>
        /// 初始化注入模式
        /// </summary>
        /// <returns>注入模式列表</returns>
        private List<InjectionPattern> InitializePatterns()
        {
            return new List<InjectionPattern>
            {
                // SQL注入模式
                new InjectionPattern
                {
                    Name = "SQL注入 - 单引号",
                    Description = "检测包含单引号的SQL注入尝试",
                    RegexPattern = @"'(\s)*(--|#|/\*|;|or|and|union|select|insert|update|delete|drop|alter|exec|xp_)",
                    RiskLevel = RiskLevel.High,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "SQL注入 - UNION SELECT",
                    Description = "检测UNION SELECT语句",
                    RegexPattern = @"union(\s)+select",
                    RiskLevel = RiskLevel.Critical,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "SQL注入 - 注释",
                    Description = "检测SQL注释",
                    RegexPattern = @"(--|#|/\*)(\s)*(\w+)(\s)*(=|<|>|!)",
                    RiskLevel = RiskLevel.Medium,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "SQL注入 - 布尔条件",
                    Description = "检测布尔条件注入",
                    RegexPattern = @"(\s)+(or|and)(\s)+['""0-9](\s)*(=|<|>|!)(\s)*['""0-9]",
                    RiskLevel = RiskLevel.High,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "SQL注入 - 堆叠查询",
                    Description = "检测堆叠查询注入",
                    RegexPattern = @";(\s)*(select|insert|update|delete|drop|alter|exec|xp_)",
                    RiskLevel = RiskLevel.Critical,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "SQL注入 - 时间延迟",
                    Description = "检测时间延迟注入",
                    RegexPattern = @"(waitfor|sleep|pg_sleep|benchmark)(\s)*\(",
                    RiskLevel = RiskLevel.High,
                    InjectionType = InjectionType.SqlInjection
                },
                
                // XSS注入模式
                new InjectionPattern
                {
                    Name = "XSS注入 - 脚本标签",
                    Description = "检测脚本标签",
                    RegexPattern = @"<(\s)*script",
                    RiskLevel = RiskLevel.High,
                    InjectionType = InjectionType.XssInjection
                },
                new InjectionPattern
                {
                    Name = "XSS注入 - 事件处理",
                    Description = "检测事件处理程序",
                    RegexPattern = @"(on\w+)(\s)*=(\s)*['""]",
                    RiskLevel = RiskLevel.Medium,
                    InjectionType = InjectionType.XssInjection
                },
                new InjectionPattern
                {
                    Name = "XSS注入 - JavaScript函数",
                    Description = "检测JavaScript函数调用",
                    RegexPattern = @"(alert|confirm|prompt|eval|document\.cookie|document\.write|window\.location)(\s)*\(",
                    RiskLevel = RiskLevel.High,
                    InjectionType = InjectionType.XssInjection
                },
                
                // 命令注入模式
                new InjectionPattern
                {
                    Name = "命令注入 - 系统命令",
                    Description = "检测系统命令注入",
                    RegexPattern = @"(;|\||\|\||&&)(\s)*(cmd|powershell|bash|sh|wget|curl|nc|netcat)",
                    RiskLevel = RiskLevel.Critical,
                    InjectionType = InjectionType.CommandInjection
                },
                
                // 新增检测模式
                new InjectionPattern
                {
                    Name = "SQL注入 - 十六进制编码",
                    Description = "检测十六进制编码的SQL注入",
                    RegexPattern = @"0x[0-9a-f]+",
                    RiskLevel = RiskLevel.High,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "SQL注入 - 存储过程",
                    Description = "检测存储过程滥用",
                    RegexPattern = @"(exec|execute|sp_|xp_|sys\.)\w+",
                    RiskLevel = RiskLevel.Critical,
                    InjectionType = InjectionType.SqlInjection
                },
                new InjectionPattern
                {
                    Name = "XSS注入 - HTML属性",
                    Description = "检测HTML属性注入",
                    RegexPattern = @"\w+(\s)*=(\s)*['""]?javascript:",
                    RiskLevel = RiskLevel.Medium,
                    InjectionType = InjectionType.XssInjection
                }
            };
        }

        /// <summary>
        /// 检测值是否包含注入
        /// </summary>
        /// <param name="value">要检查的值</param>
        /// <returns>匹配的注入模式，如果没有匹配则返回null</returns>
        public InjectionPattern? DetectInjection(string? value)
        {
            if (string.IsNullOrEmpty(value))
                return null;

            // 转换为小写进行检查
            string lowerValue = value.ToLower();

            foreach (var pattern in _patterns.Where(p => p.IsEnabled))
            {
                if (Regex.IsMatch(lowerValue, pattern.RegexPattern, RegexOptions.IgnoreCase))
                {
                    return pattern;
                }
            }

            return null;
        }

        /// <summary>
        /// 生成修复建议
        /// </summary>
        /// <param name="result">扫描结果</param>
        /// <returns>修复建议</returns>
        public string GenerateRemediationAdvice(ScanResult result)
        {
            return result.InjectionType switch
            {
                InjectionType.SqlInjection => 
                    "使用参数化查询替代字符串拼接，实施输入验证，对特殊字符进行转义。",
                
                InjectionType.XssInjection => 
                    "对输出进行HTML编码，实施内容安全策略(CSP)，使用XSS过滤库。",
                
                InjectionType.CommandInjection => 
                    "避免直接执行用户输入的命令，使用安全API，实施严格的输入验证和白名单过滤。",
                
                _ => "实施输入验证，对特殊字符进行转义，使用安全的API。"
            };
        }
    }
}